/*	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

#include <SoftwareSerial.h>
#include "SM5100B.h"


SM5100B::SM5100B(uint8_t tx, uint8_t rx, uint32_t pin) : cell(tx,rx), pin(pin) {

	gsm_status=SM5100B_NOTINIT; 
	cell.begin(9600);//Al módulo gsm

}


int SM5100B::getStatus()
{
	return(gsm_status);
}

//*************
// Inicia modulo GSM
//*************
void SM5100B::begin()
{
//Restart GSM module
//how?

while (gsm_status==SM5100B_NOTINIT){
	//First of all module is rebooted to have a clean start
	Serial.println("AT+CFUN=1,1");
	cell.println("AT+CFUN=1,1");
	
	if (EsperamosOK("+SIND: 7")) {
	//Error
	Serial.println("Error SM5100B begin: Timed out when waiting for +SIND: 7");
	gsm_status=SM5100B_NOTINIT;
	continue;
	}
		gsm_status=SM5100B_INITNOPIN;//preReady
		
		Serial.println("AT+SBAND=4");
		cell.println("AT+SBAND=4");
		EsperamosOK("OK");
		
		Serial.println("AT+CPIN="+(String)pin);
		cell.println("AT+CPIN="+(String)pin);
		EsperamosOK("OK");


		
		if (gsm_status==SM5100B_INITNOPIN){
			if (EsperamosOK("+SIND: 4")){
				//Error
				Serial.println("Error SM5100B begin: Timed out when waiting for +SIND: 4");
				gsm_status=SM5100B_NOTINIT;
				continue;
			}
			
			Serial.println("AT+CMGF=1");
			gsm_status=SM5100B_INITPIN;//Ready
			cell.println("AT+CMGF=1");//Modo texto lectura SMS
			if (EsperamosOK("OK")){
				//Error
				Serial.println("Error SM5100B begin: Timed out when waiting for OK when changing to SMS text mode");
				gsm_status=SM5100B_NOTINIT;
				continue;
			}
		}
  }
}

//*************
// Inicia conexion GPRS y conecta con la web deseada
//*************
void SM5100B::begin_gprs()
{
  if (gsm_status==SM5100B_INITPIN){
      // Llamar y conectarse a internet
      cell.println("AT+CGATT?");                                          // Activar GPRS 1= si => AT+CGATT = 0 desactiva
      EsperamosOK("OK");
      
      cell.println("AT+CGATT=1");                                          // Activar GPRS 1= si => AT+CGATT = 0 desactiva
      EsperamosOK("OK");

      cell.println("AT+CGATT?");                                          // Activar GPRS 1= si => AT+CGATT = 0 desactiva
      EsperamosOK("OK");
    
      //AT+CGDCONT=1, "IP", "airtelwap.es"
      cell.println("AT+CGDCONT=1, \"IP\", \"airtelwap.es\"");      // Setup PDP 
      //Serial.println("Direccion: ");
      EsperamosOK("OK");
      
      //AT+CGPCO=0, "wap@wap", "wap125", 1
      cell.println("AT+CGPCO=0, \"wap@wap\", \"wap125\", 1");                   // Parametros PDP
      //Serial.println("Clave: ");
      EsperamosOK("OK");
      
      // Activamos conexion GPRS
      cell.println("AT+CGACT=1,1");      // Activar GPRS
      //Serial.println("CGACT: ");
      EsperamosOK("OK");  
      delay(100);

  gsm_status=SM5100B_GPRSINIT;
  }
}
    
//*****************
// HTTP Get Request
//*****************
void SM5100B::http_get_request(String server, String port, String request){
  if (gsm_status==SM5100B_GPRSINIT){
    //AT+SDATACONF=1, "TCP", "glownt.net78.net", 80
    // Buscar una direccion en internet
    cell.println("AT+SDATACONF=1, \"TCP\", \"" + server + "\", " + port);    // Host y puerto
	Serial.println("AT+SDATACONF=1, \"TCP\", \"" + server + "\", " + port);    // Host y puerto
    Serial.println("TCP: ");
    EsperamosOK("");
      
    // Iniciar comunicacion
    cell.println("AT+SDATASTART=1,1");         // Iniciar comunicacion TCP/UDP
    Serial.println("SDATASTART: ");
    EsperamosOK("");
        
    // Estado comunicaciones
	do {
		delay(500);
		cell.println("AT+SDATASTATUS=1");                                  // Consulta estado, hacer varias veces esta consulta.
		Serial.println("SDATASTATUS: ");
	} while (EsperamosOK("1,1,0102,"));
    //  +SOCKSTATUS:  1,0,0104,0,0,0  (0 means socket not connected, 0104 means socket is connecting)
    //  +SOCKSTATUS:  1,1,0102,0,0,0 (1 means socket connected)
    /*delay(1000);
    // Estado comunicaciones
    cell.println("AT+SDATASTATUS=1");                                  // Consulta estado, hacer varias veces esta consulta.
    Serial.println("SDATASTATUS: ");
    EsperamosOK("");*/  

    
	int len = 16 + request.length() + 8 + server.length() + 23;
    cell.println("AT+SDATATSEND=1,"+String(len));
    Serial.println("AT+SDATATSEND=1,"+String(len)+": ");
    EsperamosOK("> ");  

	
	//cell.print("GET /save_data.php?user=test&temps="+String(tempc)+"&times=20121228170000 HTTP/1.1\r\n"); // SIZE: 69
    cell.print("GET /" + request + " HTTP/1.1\r\n"); // SIZE: 16+len(request)
    delay(100);
    cell.print("Host: " + server + "\r\n"); // SIZE: 8+len(server)
    delay(100);
    cell.print("User-Agent: Arduino\r\n\r\n"); // SIZE: 23
    delay(100);
    cell.write(26);								// SIZE: 1
    /*byte ctrlz = 26;
    cell.print(ctrlz);
    cell.print(ctrlz);
    cell.print(ctrlz); */// ctrl+z character: send the packet
    if (EsperamosOK("OK")==0)
		Serial.println("Enviado!");
    if (EsperamosOK("STCPD")==0){
      Serial.println("Recibida respuesta HTTP. Procesando...");
      cell.println("AT+SDATATREAD=1");
      //TODO:ProcesarRespuestaHTTP();
	  delay(10);
	  EsperamosOK("");
    }
    cell.println("AT+SDATATREAD=1");
	EsperamosOK("");
	cell.println("AT+SDATATREAD=1");
	EsperamosOK("");
	
    //Cerramos la conexión
    cell.println("AT+SDATASTART=1,0");         // Iniciar comunicacion TCP/UDP
    Serial.println("SDATASTART: ");
    EsperamosOK("OK");
  } else {
	Serial.println("Error bad module status :(");
  }
}
  


//*****************
// Esperar respuesta
//*****************
int SM5100B::EsperamosOK(const char* esperado){
  unsigned long espera;
  espera = millis();
  if (esperado==""){
    while((cell.available()<1) && (millis()-espera < 50000)){} //Esperamos 50 segundos max
    
    while(cell.available()>0) {
      char incoming_char=cell.read();    //Get the character from the cellular serial port.
      Serial.print(incoming_char);
      delay(2);
    }
    return(0); //ok
  }
  else
  {
    while((cell.available()<1) && (millis()-espera < 20000)){} //Esperamos 30 segundos max
    String last = "";
    while(true) {
      if (cell.available()>0){
        char incoming_char=cell.read();    //Get the character from the cellular serial port.
        Serial.print(incoming_char);
        last=last+incoming_char;
        
        delay(2);
      } 
      else if (last.indexOf(esperado)!=-1){
          return(0); //ok
      }
      if ((millis()-espera) > 30000)
          return(1); //timed out
    }
  }
}

